import { DeleteOutlined, PlusOutlined, SettingOutlined } from '@ant-design/icons';
import { Button, Space } from 'antd';
import React, { useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { NodeProps } from 'reactflow';
import { useContextSelector } from 'use-context-selector';

import CollapsibleSection from '@/components/CollapsibleSection';
import EmptyTip from '@/components/EmptyTip';
import { VariableItemType } from '@/types/app/type';
import { FlowNodeOutputTypeEnum, NodeInputKeyEnum } from '@/types/workflow/constant';
import { FlowNodeInputItemType, FlowNodeOutputItemType } from '@/types/workflow/io';
import { FlowNodeItemType } from '@/types/workflow/node';
import { UserInputFormItemType } from '@/types/workflow/template/system/interactive/type';

import { WorkflowContext } from '../../../context';
import NodeCard from '../render/NodeCard';
import RenderInput from '../render/RenderInput';
import RenderOutput from '../render/RenderOutput';
import VariableItem from '../system/VariableItem';

import InputFormEditModal, { defaultFormInput } from './InputFormEditModal';

function NodeFormInput({ data, selected }: NodeProps<FlowNodeItemType>) {
  const { nodeId, inputs, outputs } = data;
  const { t } = useTranslation();
  const { onChangeNode } = useContextSelector(WorkflowContext, (ctx) => ctx);

  const [expandedSections, setExpandedSections] = useState<Set<'output' | 'input' | 'params'>>(
    new Set(['input']),
  );

  const toggleSection = (section: 'output' | 'input' | 'params') => {
    setExpandedSections((prev) => {
      const newSet = new Set(prev);
      if (newSet.has(section)) {
        newSet.delete(section);
      } else {
        newSet.add(section);
      }
      return newSet;
    });
  };

  const [editField, setEditField] = useState<UserInputFormItemType>();

  const CustomComponent = useMemo(
    () => ({
      [NodeInputKeyEnum.userInputForms]: ({ value, key, ...props }: FlowNodeInputItemType) => {
        const inputs = (value as UserInputFormItemType[]) ?? [];

        const onSubmit = (data: UserInputFormItemType) => {
          if (!editField?.key) {
            onChangeNode({
              nodeId,
              type: 'updateInput',
              key,
              value: {
                ...props,
                key,
                value: inputs.concat(data),
              },
            });
            onChangeNode({
              nodeId,
              type: 'addOutput',
              value: {
                id: data.key,
                valueType: data.valueType,
                key: data.key,
                label: data.label,
                type: FlowNodeOutputTypeEnum.static,
              },
            });
          } else {
            const output = outputs.find((output) => output.key === editField.key);
            onChangeNode({
              nodeId,
              type: 'updateInput',
              key,
              value: {
                ...props,
                key,
                value: inputs.map((input) => (input.key === editField.key ? data : input)),
              },
            });
            onChangeNode({
              nodeId,
              type: 'replaceOutput',
              key: editField.key,
              value: {
                ...(output as FlowNodeOutputItemType),
                valueType: data.valueType,
                key: data.key,
                label: data.label,
              },
            });
          }
        };

        const onDelete = (valueKey: string) => {
          onChangeNode({
            nodeId,
            type: 'updateInput',
            key,
            value: {
              ...props,
              key,
              value: inputs.filter((input) => input.key !== valueKey),
            },
          });
          onChangeNode({
            nodeId,
            type: 'delOutput',
            key: valueKey,
          });
        };

        const columns = [
          {
            title: t('workflow:user_form_input_name'),
            dataIndex: 'label',
            key: 'label',
          },
          {
            title: t('workflow:user_form_input_description'),
            dataIndex: 'description',
            key: 'description',
            render: (text: string) => text || '-',
          },
          {
            title: t('common.Require Input'),
            dataIndex: 'required',
            key: 'required',
            align: 'center',
            render: (required: boolean) => (required ? '✅' : ''),
          },
          {
            title: t('user:operations'),
            key: 'actions',
            align: 'center',
            render: (_: any, record: UserInputFormItemType) => (
              <Space>
                <Button
                  type="text"
                  icon={<SettingOutlined />}
                  onClick={() => setEditField(record)}
                />
                <Button
                  type="text"
                  danger
                  icon={<DeleteOutlined />}
                  onClick={() => {
                    onDelete(record.key);
                  }}
                />
              </Space>
            ),
          },
        ];
        const handleEditVariable = (variable: UserInputFormItemType | VariableItemType) => {
          setEditField(variable as UserInputFormItemType);
        };

        const handleDeleteVariable = (variable: UserInputFormItemType | VariableItemType) => {
          onDelete((variable as UserInputFormItemType).key);
        };

        return (
          <div>
            <div className="nodrag mb-3 flex cursor-default">
              {/* <FormLabel>{t('user_form_input_config_label')}</FormLabel> */}
              <div className="flex-1" />

              {!!editField && (
                <InputFormEditModal
                  defaultValue={editField}
                  keys={inputs.map((item) => item.key)}
                  onClose={() => {
                    setEditField(undefined);
                  }}
                  onSubmit={onSubmit}
                />
              )}
            </div>

            {/* <Table bordered size="small" pagination={false} dataSource={inputs} columns={columns} /> */}

            <div className="flex flex-col gap-2">
              {!inputs || inputs.length === 0 ? (
                <EmptyTip text="还没有配置输入参数哦~" />
              ) : (
                inputs.map((item) => (
                  <VariableItem
                    key={item.key}
                    variable={item}
                    handleEditVariable={handleEditVariable}
                    handleDeleteVariable={handleDeleteVariable}
                  />
                ))
              )}
            </div>

            <div className="mt-4 flex items-center justify-center">
              <Button
                icon={<PlusOutlined />}
                type="text"
                onClick={() => {
                  setEditField(defaultFormInput);
                }}
              >
                添加输入参数
              </Button>
            </div>
          </div>
        );
      },
    }),
    [t, editField, onChangeNode, nodeId, outputs],
  );

  const Render = useMemo(() => {
    return (
      <NodeCard minW="400px" selected={selected} {...data}>
        <div className="flex flex-col gap-3 space-y-0">
          <CollapsibleSection
            title="输入参数配置"
            subtitle="配置需要用户输入的参数，在对话过程中引导用户输入特定内容"
            isExpanded={expandedSections.has('input')}
            onToggle={() => toggleSection('input')}
            type="input"
          >
            <div className="space-y-2">
              <RenderInput
                nodeId={nodeId}
                flowInputList={inputs}
                CustomComponent={CustomComponent}
              />
            </div>
          </CollapsibleSection>
          <CollapsibleSection
            title={t('workflow.node.output')}
            subtitle={t('workflow.node.output_desc')}
            isExpanded={expandedSections.has('output')}
            onToggle={() => toggleSection('output')}
            type="output"
            className="pb-3"
          >
            <div className="max-h-[200px] overflow-y-auto px-2">
              <RenderOutput nodeId={nodeId} flowOutputList={outputs} />
            </div>
          </CollapsibleSection>
        </div>
      </NodeCard>
    );
  }, [CustomComponent, data, expandedSections, inputs, nodeId, outputs, selected, t]);

  return Render;
}

export default React.memo(NodeFormInput);
